package com.huazai.yangge.completable.lock;

import java.util.concurrent.TimeUnit;

/**
 * 什么是对象锁，什么是类锁
 * @author huazai
 * @date 2024/2/22
 */

class Phone {
    public static synchronized void sendEmail() {
        try {
            TimeUnit.MILLISECONDS.sleep(300);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        System.out.println("=======sendEmail");
    }

    public static synchronized void sendMsg() {
        System.out.println("=======sendMsg");
    }

    public void hello() {
        System.out.println("=======hello");
    }
}

// 8种案例说明：
// 1 标准2个线程ab，请问先打印邮件还是短信
// 2 sendEmail方法中加入暂停3秒，请问先打印邮件还是短信
// 3 添加一个普通方法hello，，请问先打印邮件还是hello
// 4 有2个手机（创建连个实例对象），请问先打印邮件还是短信
// 5 有2个静态同步方法，1部手机，请问先打印邮件还是短信
// 6 有2个静态同步方法，2部手机，请问先打印邮件还是短信
// 7 有1个静态同步方法，有1个普通同步方法，1部手机，请问先打印邮件还是短信
// 8 有1个静态同步方法，有1个普通同步方法，1部手机，请问先打印邮件还是短信

// 解答： 类锁、对象锁
// 1 2  如果一个对象里面有多个synchronized方法，某一时刻内，一个线程调用其中一个synchronized方法，其他线程都需要等待，换句话说某一时
// 刻只能有一个线程去访问这些synchronized方法
// 锁的是当前对象this，被锁定后，其他线程都不能进入当前对象的其他synchronized方法

// 3 4 加一个普通方法后发现和同步锁物管
// 换成2个对象后，不是同一把锁了，情况立刻变化

// 5 6 静态同步方法，锁的是当前的类的class对象，如phone.class唯一的一个模板，对于同步方法快，所得是synchronized括号内的对象

// 7 所有的静态同步方法用的都是同一把锁-->类对象本生，就是我们所说的唯一模板class
// 实例对象this和class，这两把锁不是同一个对象，所以静态同步方法和普通的同步方法之间是不会有状态条件的
// 一个静态同步方法获取锁后，其他的静态同步方法都必须登台该方法释放后才能获取锁

public class LockDemo {
    // 锁的事
    // 悲观锁
    // 乐观锁
    public static void main(String[] args) throws InterruptedException {
        Phone phone = new Phone();
        Phone phone1 = new Phone();
        new Thread(() -> {
            phone.sendEmail();
        }, "aaa").start();

        TimeUnit.MILLISECONDS.sleep(200);

        new Thread(() -> {
            //phone.sendMsg();
            //phone.hello();
            phone1.sendMsg();
        }, "bbb").start();
    }
}
